/**
 * Copyright (c) 2024 OceanBase
 * OceanBase Migration Service LogProxy is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#include "common/function_type.h"
namespace etransfer {
namespace common {
const char* const FunctionTypeUtil::function_type_names[] = {
    "ASCII",
    "LOWER",
    "UPPER",
    "CAST",
    "ABS",
    "SUBSTR",
    "SUBSTRING",
    "SUBSTRING_INDEX",
    "REPLACE",
    "TRIM",
    "LTRIM",
    "RTRIM",
    "LPAD",
    "RPAD",
    "NOW",
    "LEFT",
    "REPEAT",
    "REVERSE",
    "RIGHT",
    "ADDDATE",
    "DATE_ADD",
    "ADDTIME",
    "SUBDATE",
    "DATE_SUB",
    "SUBTIME",
    "DATE",
    "DATEDIFF",
    "TIMESTAMPDIFF",
    "TIMESTAMPADD",
    "TIMEDIFF",
    "DAY",
    "DAYOFMONTH",
    "DAYOFWEEK",
    "DAYOFYEAR",
    "MONTHNAME",
    "MAKETIME",
    "MAKEDATE",
    "TIME",
    "WEEK",
    "YEAR",
    "HOUR",
    "MINUTE",
    "MONTH",
    "QUARTER",
    "SECOND",
    "INTERVAL",
    "LOCALTIME",
    "MICROSECOND",
    "CHAR_LENGTH",
    "CHARACTER_LENGTH",
    "CHARACTER",
    "CONCAT_WS",
    "FIELD",
    "FIND_IN_SET",
    "FORMAT",
    "INSERT",
    "LOCATE",
    "LCASE",
    "POSITION",
    "SPACE",
    "STRCMP",
    "UCASE",
    "SEC_TO_TIME",
    "COUNT",
    "MAX",
    "MIN",
    "PERIOD_DIFF",
    "TIME_TO_SEC",
    "TO_DAYS",
    "WEEKDAY",
    "WEEKOFYEAR",
    "CONCAT",
    "EXTRACT",
    "MOD",
    "CURRENT_TIMESTAMP",
    "CURRENT_TIME",
    "CURTIME",
    "TIMESTAMP",
    "SYSDATE",
    "LOCALTIMESTAMP",
    "CURRENT_DATE",
    "CURDATE",
    "UTC_TIMESTAMP",
    "SQRT",
    "JSON_ARRAY",
    "JSON_OBJECT",
    "JSON_QUOTE",
    "JSON_UNQUOTE",
    "JSON_EXTRACT",
    "JSON_KEYS",
    "JSON_SEARCH",
    "JSON_APPEND",
    "JSON_ARRAY_APPEND",
    "JSON_MERGE",
    "JSON_REMOVE",
    "JSON_DEPTH",
    "JSON_LENGTH",
    "JSON_REPLACE",
    "JSON_SET",
    "JSON_MERGE_PRESERVE",
    "JSON_MERGE_PATCH",
    "AVG",
    "SUM",
    "CONCAT_PARAMS_WITH_SPACE",
    "CONCAT_PARAMS_WITH_DOT",
    "UNKNOWN"};

static_assert(sizeof(FunctionTypeUtil::function_type_names) / sizeof(char*) ==
                  static_cast<int>(FunctionType::UNKNOWN) + 1,
              "FunctionType sizes don't match");

#define MAP_ENTRY(type) \
  { #type, FunctionType::type }
const std::unordered_map<std::string, FunctionType>
    FunctionTypeUtil::string_to_functiontype = {
        MAP_ENTRY(ASCII),
        MAP_ENTRY(LOWER),
        MAP_ENTRY(UPPER),
        MAP_ENTRY(CAST),
        MAP_ENTRY(ABS),
        MAP_ENTRY(SUBSTR),
        {"SUBSTRING", FunctionType::SUBSTR},
        MAP_ENTRY(SUBSTRING_INDEX),
        MAP_ENTRY(REPLACE),
        MAP_ENTRY(TRIM),
        MAP_ENTRY(LTRIM),
        MAP_ENTRY(RTRIM),
        MAP_ENTRY(LPAD),
        MAP_ENTRY(RPAD),
        MAP_ENTRY(NOW),
        MAP_ENTRY(LEFT),
        MAP_ENTRY(REPEAT),
        MAP_ENTRY(REVERSE),
        MAP_ENTRY(RIGHT),
        MAP_ENTRY(ADDDATE),
        {"DATE_ADD", FunctionType::ADDDATE},
        MAP_ENTRY(ADDTIME),
        MAP_ENTRY(SUBDATE),
        {"DATE_SUB", FunctionType::SUBDATE},
        MAP_ENTRY(SUBTIME),
        MAP_ENTRY(DATE),
        MAP_ENTRY(DATEDIFF),
        MAP_ENTRY(TIMESTAMPDIFF),
        MAP_ENTRY(TIMESTAMPADD),
        MAP_ENTRY(TIMEDIFF),
        MAP_ENTRY(DAY),
        MAP_ENTRY(DAYOFMONTH),
        MAP_ENTRY(DAYOFWEEK),
        MAP_ENTRY(DAYOFYEAR),
        MAP_ENTRY(MONTHNAME),
        MAP_ENTRY(MAKETIME),
        MAP_ENTRY(MAKEDATE),
        MAP_ENTRY(TIME),
        MAP_ENTRY(WEEK),
        MAP_ENTRY(YEAR),
        MAP_ENTRY(HOUR),
        MAP_ENTRY(MINUTE),
        MAP_ENTRY(MONTH),
        MAP_ENTRY(QUARTER),
        MAP_ENTRY(SECOND),
        MAP_ENTRY(INTERVAL),
        MAP_ENTRY(LOCALTIME),
        MAP_ENTRY(MICROSECOND),
        MAP_ENTRY(CHAR_LENGTH),
        {"CHARACTER_LENGTH", FunctionType::CHAR_LENGTH},
        MAP_ENTRY(CHARACTER),
        MAP_ENTRY(CONCAT_WS),
        MAP_ENTRY(FIELD),
        MAP_ENTRY(FIND_IN_SET),
        MAP_ENTRY(FORMAT),
        MAP_ENTRY(INSERT),
        MAP_ENTRY(LOCATE),
        MAP_ENTRY(LCASE),
        MAP_ENTRY(POSITION),
        MAP_ENTRY(SPACE),
        MAP_ENTRY(STRCMP),
        MAP_ENTRY(UCASE),
        MAP_ENTRY(SEC_TO_TIME),
        MAP_ENTRY(COUNT),
        MAP_ENTRY(MAX),
        MAP_ENTRY(MIN),
        MAP_ENTRY(PERIOD_DIFF),
        MAP_ENTRY(TIME_TO_SEC),
        MAP_ENTRY(TO_DAYS),
        MAP_ENTRY(WEEKDAY),
        MAP_ENTRY(WEEKOFYEAR),
        MAP_ENTRY(CONCAT),
        MAP_ENTRY(EXTRACT),
        MAP_ENTRY(MOD),
        MAP_ENTRY(CURRENT_TIMESTAMP),
        MAP_ENTRY(CURRENT_TIME),
        MAP_ENTRY(CURTIME),
        MAP_ENTRY(TIMESTAMP),
        MAP_ENTRY(SYSDATE),
        MAP_ENTRY(LOCALTIMESTAMP),
        MAP_ENTRY(CURRENT_DATE),
        MAP_ENTRY(CURDATE),
        MAP_ENTRY(UTC_TIMESTAMP),
        MAP_ENTRY(SQRT),
        MAP_ENTRY(JSON_ARRAY),
        MAP_ENTRY(JSON_OBJECT),
        MAP_ENTRY(JSON_QUOTE),
        MAP_ENTRY(JSON_UNQUOTE),
        MAP_ENTRY(JSON_EXTRACT),
        MAP_ENTRY(JSON_KEYS),
        MAP_ENTRY(JSON_SEARCH),
        MAP_ENTRY(JSON_APPEND),
        MAP_ENTRY(JSON_ARRAY_APPEND),
        MAP_ENTRY(JSON_MERGE),
        MAP_ENTRY(JSON_REMOVE),
        MAP_ENTRY(JSON_DEPTH),
        MAP_ENTRY(JSON_LENGTH),
        MAP_ENTRY(JSON_REPLACE),
        MAP_ENTRY(JSON_SET),
        MAP_ENTRY(JSON_MERGE_PRESERVE),
        MAP_ENTRY(JSON_MERGE_PATCH),
        MAP_ENTRY(AVG),
        MAP_ENTRY(SUM),
        MAP_ENTRY(CONCAT_PARAMS_WITH_SPACE),
        MAP_ENTRY(CONCAT_PARAMS_WITH_DOT),
        MAP_ENTRY(UNKNOWN),
};

FunctionType FunctionTypeUtil::GetFunctionType(
    const std::string& function_name) {
  auto iter = string_to_functiontype.find(function_name);
  FunctionType function_type = FunctionType::UNKNOWN;
  if (iter != string_to_functiontype.end()) {
    function_type = iter->second;
  }
  return function_type;
}

const char* FunctionTypeUtil::GetFunctionName(FunctionType function_type) {
  return function_type_names[static_cast<int>(function_type)];
}
}  // namespace common

}  // namespace etransfer
